/********************************** (C) COPYRIGHT *******************************
 * File Name          : main.c
 * Author             : WCH
 * Version            : V1.0.0
 * Date               : 2021/06/06
 * Description        : Main program body.
 *********************************************************************************
 * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
 * Attention: This software (modified or not) and binary are used for 
 * microcontroller manufactured by Nanjing Qinheng Microelectronics.
 *******************************************************************************/

/*
 *@Note
 *USART Print debugging routine:
 *USART1_Tx(PA9).
 *This example demonstrates using USART1(PA9) as a print debug port output.
 *
 */

#include "debug.h"
#include "USB2Device/ch32v20x_device.h"

/* Global typedef */

/* Global define */

/* Global Variable */

/*********************************************************************
 * @fn      main
 *
 * @brief   Main program.
 *
 * @return  none
 */
int main(void)
{
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
    SystemCoreClockUpdate();
    Delay_Init();
    USART_Printf_Init(115200);
    printf("SystemClk:%d\r\n", SystemCoreClock);
    printf( "ChipID:%08x\r\n", DBGMCU_GetCHIPID() );
    printf("This is printf example\r\n");

    USBFS_Buffer_Init();
    USBFS_RCC_Init();
    USBFS_Device_Init( ENABLE );
    NVIC_EnableIRQ(USBHD_IRQn);

    uint8_t ret;
    while(1)
    {
        if(USBFS_DevEnumStatus)
        {
            /* Data Transfer */
            if(USBFSD_RingBuffer_Comm.RemainPack)
            {
                uint8_t *pbuf = &USBFSD_Data_Buffer[(USBFSD_RingBuffer_Comm.DealPtr) * DEF_USBD_FS_PACK_SIZE];
                uint16_t len = USBFSD_RingBuffer_Comm.PackLen[USBFSD_RingBuffer_Comm.DealPtr];
                ret = USBFS_Endp_DataUp(DEF_UEP2, pbuf, len, DEF_UEP_DMA_LOAD);
                if( ret == 0 )
                {
                    NVIC_DisableIRQ(USBHD_IRQn);
                    USBFSD_RingBuffer_Comm.RemainPack--;
                    USBFSD_RingBuffer_Comm.DealPtr++;
                    if(USBFSD_RingBuffer_Comm.DealPtr == DEF_Ring_Buffer_Max_Blks)
                    {
                        USBFSD_RingBuffer_Comm.DealPtr = 0;
                    }
                    NVIC_EnableIRQ(USBHD_IRQn);
                }
            }

            /* Monitor whether the remaining space is available for further downloads */
            if(USBFSD_RingBuffer_Comm.RemainPack < (DEF_Ring_Buffer_Max_Blks - DEF_RING_BUFFER_RESTART))
            {
                if(USBFSD_RingBuffer_Comm.StopFlag)
                {
                    NVIC_DisableIRQ(USBHD_IRQn);
                    USBFSD_RingBuffer_Comm.StopFlag = 0;
                    NVIC_EnableIRQ(USBHD_IRQn);
                    USBOTG_FS->UEP1_RX_CTRL = (USBOTG_FS->UEP1_RX_CTRL & ~USBFS_UEP_R_RES_MASK) | USBFS_UEP_R_RES_ACK;
                }
            }
        }
    }
}
